/*
 * File     : DynamicSize.java
 * Created  : 27 May 2011
 *
 * Copyright © 2011 Matthew Wilson (mj. {my-surname} .uk {at} gmail.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.dni;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.Buffer;

import com.googlecode.dni.type.NativeStringBuffer;
import com.googlecode.dni.type.nativetype.NativeInt;

/**
 * <p>
 *  Annotates a structure field's getter to indicate that the value is of a size
 *  indicated by another field.
 * </p>
 * <p>
 *  When on a structure field, the annotation indicates which other field gives
 *  the dynamic size.  The annotated structure field must be a {@link Buffer}
 *  or a {@link NativeStringBuffer}.  The referenced structure field must be an
 *  integral type (<code>byte</code>, <code>short</code>, <code>char</code>,
 *  <code>int</code>, or <code>long</code>); the field may be marked with a
 *  native type (for example, {@link NativeInt}).
 * </p>
 * <p>
 *  When the field's value is set, the referenced field is read, and the buffer
 *  is checked to determine if it is sufficiently sized.
 *  For {@link Buffer} types, there must be at least that number of elements
 *  remaining.
 *  For {@link NativeStringBuffer} types, the capacity must be precisely that
 *  number of {@link NativeStringBuffer#codeSize() coded units}.
 *  If the size is incorrect, an exception is thrown.
 *  If the read size is negative, or greater than or equal to 2<sup>31</sup>, an
 *  exception is thrown.
 *  <!-- TODO v1.0 why the difference between Buffer and NativeStringBuffer? -->
 * </p>
 * <p>
 *  When the field's value is read, the referenced field is read.  If the read
 *  size is negative, or greater than or equal to 2<sup>31</sup>, an exception
 *  is thrown.  For {@link Buffer} types, the update method will set the
 *  position and limit to match the pointer and the size; if this would take the
 *  position and/or limit out of range, the method does nothing and returns
 *  <code>false</code>.  For {@link NativeStringBuffer}, the getter method will
 *  return a buffer with the read capacity.
 * </p>
 *
 * @author Matthew Wilson
 */
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.METHOD )
@Documented
public @interface DynamicSize
{

    /**
     * The name of the field indicating the size.  The field's type must be an
     * integral type.
     *
     * @return the name of the field
     */
    String value();

}
